//
// Created by fanghr on 18-3-27.
//

#include <stdio.h>
#include <stdlib.h>
#include <linux/types.h>
#include <stdint.h>

#include "../include/binder.h"
#include "test_server.h"

//int svcmgr_publish(struct binder_state *bs, uint32_t target, const char *name, void *ptr) {
//    int status;
//    unsigned iodata[512 / 4];
//    struct binder_io msg, reply;
//    bio_init(&msg, iodata, sizeof(iodata), 4);
//    bio_put_uint32(&msg, 0);  // strict mode include
//    bio_put_string16_x(&msg, SVC_MGR_NAME);
//    bio_put_string16_x(&msg, name);
//    bio_put_obj(&msg, ptr);
//    /*远程调用ServiceManager的do_add_service函数*/
//    if (binder_call(bs, &msg, &reply, target, SVC_MGR_ADD_SERVICE))
//        return -1;
//    status = bio_get_uint32(&reply);
//    binder_done(bs, &msg, &reply);
//    return status;
//}

void sayhello(void) {
    static int cnt = 0;
    fprintf(stderr, "say hello : %d\n", cnt++);
}

int sayhello_to(char *name) {
    static int cnt = 0;
    fprintf(stderr, "say hello to %s : %d\n", name, cnt++);
    return cnt;
}

int hello_service_handler(struct binder_state *bs,
                          struct binder_transaction_data *txn,
                          struct binder_io *msg,
                          struct binder_io *reply) {
    /* 根据txn->code知道要调用哪一个函数
     * 如果需要参数, 可以从msg取出
     * 如果要返回结果, 可以把结果放入reply
     */
    /* sayhello
     * sayhello_to
     */

    uint16_t *s;
    char name[512];
    size_t len;
    uint32_t handle;
    uint32_t strict_policy;
    int i;

    strict_policy = bio_get_uint32(msg);
    switch (txn->code) {
        case HELLO_SVR_CMD_SAYHELLO:
            sayhello();
            return 0;
        case HELLO_SVR_CMD_SAYHELLO_TO:
            /* 从msg里取出字符串 */
            s = bio_get_string16(msg, &len);
            if (s == NULL) {
                return -1;
            }
            for (i = 0; i < len; i++)
                name[i] = s[i];
            name[i] = '\0';
            /* 处理 */
            i = sayhello_to(name);
            /* 把结果放入reply */
            bio_put_uint32(reply, i);

            break;
        default:
            fprintf(stderr, "unknown code %d\n", txn->code);
            return -1;
    }
    return 0;
}

int main(int argc, char **argv) {
    int fd;
    struct binder_state *bs;
    uint32_t svcmgr = BINDER_SERVICE_MANAGER;
    uint32_t handle;
    int ret;
    /*打开并映射binder驱动*/
    bs = binder_open(128 * 1024);
    if (!bs) {
        fprintf(stderr, "failed to open binder driver\n");
        return -1;
    }
    /* 向ServiceManager注册服务 */
    ret = svcmgr_publish(bs, svcmgr, "hello", NULL);
    if (ret) {
        fprintf(stderr, "failed to publish hello service\n");
        return -1;
    }
    ret = svcmgr_publish(bs, svcmgr, "goodbye", NULL);
    if (ret) {
        fprintf(stderr, "failed to publish goodbye service\n");
    }
#if 0
    while (1)
    {
    }
#endif
    /*通过我们传入的hello_service_handler循环处理从binder驱动读出的数据*/
    binder_loop(bs, hello_service_handler);
    return 0;
}